<?php
// +----------------------------------------------------------------------
// | 知识星球[基于ThinkPHP5开发]
// +----------------------------------------------------------------------
// | Copyright (c) 2018-2019 abcblockchain.io
// +----------------------------------------------------------------------
// | 后台管理使用了HisiPHP
// +----------------------------------------------------------------------
// | Author: abcblockchain.io
// +----------------------------------------------------------------------
namespace app\common\model;

use GatewayWorker\Lib\Db as GateDb;
use think\Model;
use think\Db;

/**
 * 会员模型
 * @package app\common\model
 */
class Users extends Model
{
    // 定义时间戳字段名
    protected $createTime = 'ctime';
    protected $updateTime = false;

    // 自动写入时间戳
    protected $autoWriteTimestamp = true;

    // 对密码进行加密【注意：如果不设置密码请不要传入password字段】
    public function setPasswordAttr($value)
    {
        return password_hash($value, PASSWORD_DEFAULT);
    }

    // 对支付密码进行加密【注意：如果不设置密码请不要传入password字段】
    public function setTradepwdAttr($value)
    {
        return password_hash($value, PASSWORD_DEFAULT);
    }

    // 过滤昵称里面的表情符号
    public function setNickAttr($value)
    {
        $value = preg_replace_callback('/./u', function (array $match) {
            return strlen($match[0]) >= 4 ? '' : $match[0];
        }, $value);
        return $value;
    }

    // 最后登陆ip
    public function setLastLoginIpAttr()
    {
        return get_client_ip();
    }

    // 最后登陆ip
    public function setLastLoginTimeAttr()
    {
        return request()->time();
    }

    // 有效期
    public function setExpireTimeAttr($value)
    {
        if (!$value) return 0;
        return strtotime($value);
    }

    // 有效期
    public function getExpireTimeAttr($value)
    {
        if (!$value) return 0;
        return date('Y-m-d', $value);
    }

    public function hasLevel()
    {
        return $this->hasOne('UsersLevel', 'id', 'level_id');
    }

    /**
     * 注册
     * @param array $data 参数，可传参数account,username,password,tradedpwd,email,mobile,nick,avatar
     * @param bool $login 注册成功后自动登录
     * @author abcblockchain.io
     * @return stirng|array
     */
    public function register($data = [], $login = true)
    {
        $map = [];
        // $map['email'] = '';
        $map['mobile'] = '';
        //$map['username'] = '';
        $map['nick'] = isset($data['nick']) ? $data['nick'] : '';
        //$map['avatar'] = isset($data['avatar']) ? $data['avatar'] : '';
        $map['level_id'] = 0;
        if (isset($data['password'])) {
            $map['password'] = $data['password'];
        }
        if (isset($data['tradepwd'])) {
            $map['tradepwd'] = $data['tradepwd'];
        }

        if (isset($data['mobile'])) {
            if (is_mobile($data['mobile'])) {// 手机号
                $map['mobile'] = $data['mobile'];
            } else {
                //$this->error = '注册账号异常！';
                return false;
            }
        }
        $map['who_invit'] = $data['invit'];
        $map['invit_code'] = $this->getYqCode();
        $res = $this->validate('Users.register')->isUpdate(false)->save($map);
        if (!$res) {
            return false;
        }

        return $this->id;
    }

    /**
     * 授权登录注册，只为了提供授权登录时绑定member_id
     * @param string $data 传入数据
     * @author
     * @return stirng|array
     */
    public function oauthRegister($data = [])
    {
        $level = model('UserLevel')->where('default', 1)->find();
        $map = [];
        $map['nick'] = isset($data['nick']) ? $data['nick'] : '';
        $map['email'] = '';
        $map['mobile'] = '';
        $map['username'] = '';
        $map['avatar'] = isset($data['avatar']) ? $data['avatar'] : '';
        $map['last_login_ip'] = get_client_ip();
        $map['last_login_time'] = request()->time();
        if ($level) {
            $map['level_id'] = $level['id'];
            $map['expire_time'] = $level['expire'] > 0 ? strtotime('+ ' . $level['expire'] . ' days') : 0;
        }
        if (isset($data['email']) && is_email($data['email'])) {
            $map['email'] = $data['email'];
        }
        if (isset($data['mobile']) && is_mobile($data['mobile'])) {
            $map['mobile'] = $data['mobile'];
        }
        if (isset($data['username']) && is_username($data['username'])) {
            $map['username'] = $data['username'];
        }
        $res = $this->create($map);
        if (!$res) {
            $this->error = $this->getError() ?: '授权登录失败！';
            return false;
        }

        $map['id'] = $res->id;

        runhook('system_member_register', $map);
        return self::autoLogin($map);
    }

    /**
     * 登录
     * @param string $account 账号
     * @param string $password 密码
     * @param bool $remember 记住登录 TODO
     * @param string $field 登陆之后缓存的字段
     * @author abcblockchain.io
     * @return stirng|array
     */
    public function login($account = '', $password = '', $remember = false, $field = 'nick,username,signature,mobile,email,avatar,invit_code', $token = true)
    {
        $account = trim($account);
        $password = trim($password);
        $field = trim($field, ',');

        $map = $rule = [];
        $map['status'] = 1;

        // 匹配登录方式
        if (is_email($account)) {
            // 邮箱登录
            $map['email'] = $rule['email'] = $account;
        } elseif (is_mobile($account)) {
            // 手机号登录
            $map['mobile'] = $rule['mobile'] = $account;
        } elseif (is_username($account)) {
            // 用户名登录
            $map['username'] = $rule['username'] = $account;
        } else {
            $this->error = '登陆账号异常！';
            return false;
        }
        $rule['password'] = $password;

        if ($token !== false) {
            $rule['__token__'] = input('param.__token__') ? input('param.__token__') : $token;
            $scene = 'login_token';
        } else {
            $scene = 'login';
        }

        // 验证
        if ($this->validateData($rule, 'Users.' . $scene) != true) {
            $this->error = $this->getError();
            return false;
        }

        $member = self::where($map)->field('id,' . $field . ',level_id,password,expire_time')->find();
        if (!$member) {
            $this->error = '用户不存在或被禁用！';
            return false;
        }
        $member = $member->toArray();
        // 密码校验
        if (!password_verify($password, $member['password'])) {
            $this->error = '登陆密码错误！';
            return false;
        }
        // 检查有效期
        if ($member['expire_time'] !== 0 && strtotime($member['expire_time']) < time()) {
            $this->error = '账号已过期！';
            return false;
        }
        self::where($map)->update(['last_login_time' => time()]);
        /*$login = [];
        $login['id'] = $member['id'];
        $login['level_id'] = $member['level_id'];
        $fields = explode(',', $field);
        foreach ($fields as $v) {
            if ($v == 'password') {
                continue;
            }
            $login[$v] = $member[$v];
        }*/
        return $member;
    }

    /**
     * 获取用户信息
     * @author
     * @param $userId
     * @return array|bool|false|\PDOStatement|string|Model
     */
    public function usersInfo($userId)
    {
        if ($userId > 0) {
            $map['id'] = $userId;
            $map['status'] = 1;
            $userInfo = self::where($map)->field('id,nick,mobile,password,tradepwd,money')->find();
            return $userInfo ? $userInfo : array();
        } else {
            return false;
        }
    }

    /**
     * 编辑用户
     * @author
     * @param $userId
     * @param array $data
     * @return $this|bool
     */
    public function editUsers($userId, $data = array())
    {
        if ($userId > 0) {
            $map['id'] = $userId;
            $usersInfo = $this->usersInfo($userId);
            if (isset($data['nick']) && $data['nick'] != '') {
                $saveData['nick'] = $data['nick'];
            }

            if (isset($data['signature']) && $data['signature'] != '') {
                $saveData['signature'] = $data['signature'];
            }

            if (isset($data['avatar']) && $data['avatar'] != '') {
                $saveData['avatar'] = $data['avatar'];
            }

            if (isset($data['password']) && $data['password'] != '' && isset($data['newpassword']) && $data['newpassword']) {
                if (!password_verify($data['password'], $usersInfo['password'])) {
                    return false;
                } else {
                    $saveData['password'] = $data['newpassword'];
                }
            }

            if (isset($data['tradepwd']) && $data['tradepwd'] != '' && isset($data['newtradepwd']) && $data['newtradepwd']) {
                if (!password_verify($data['tradepwd'], $usersInfo['tradepwd'])) {
                    return false;
                } else {
                    $saveData['tradepwd'] = $data['newtradepwd'];
                }
            }

            if (!empty($saveData)) {
                $res = self::where($map)->update($saveData);
                if ($res !== false) {
                    return $res;
                } else {
                    return false;
                }
            } else {
                return false;
            }

        } else {
            return false;
        }
    }

    /**
     * 检查邀请码是否存在
     * @author
     * @param $invitCode
     * @return bool
     */
    public function checkInvitCode($invitCode)
    {
        if (empty($invitCode)) {
            return false;
        }
        $map['invit_code'] = $invitCode;
        $res = self::where($map)->field('id')->find();
        if ($res) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 检测手机是否存在
     * @author
     * @param $account
     * @return bool
     */
    public function checkAccout($account)
    {
        if (empty($account)) {
            return false;
        }
        $map['mobile'] = $account;
        $res = self::where($map)->field('id')->find();
        if ($res) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 找回重置密码
     * @author
     * @param string $account
     * @param string $password
     * @return bool
     */
    public function forgotPwd($account = '', $password = '')
    {
        $account = trim($account);
        $password = trim($password);
        $map['mobile'] = $account;
        $saveData['password'] = $password;
        $res = self::isUpdate(true, $map)->save($saveData);
        if ($res === false) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * 重置密码
     * @author
     * @param string $account
     * @param string $password
     * @return bool
     */
    public function resetTradePwd($account = '', $password = '')
    {
        $account = trim($account);
        $password = trim($password);
        $map['mobile'] = $account;
        $saveData['tradepwd'] = $password;
        $res = self::isUpdate(true, $map)->save($saveData);
        if ($res === false) {
            return false;
        } else {
            return true;
        }
    }


    /**
     * 修改密码
     * @author
     * @param string $account
     * @param string $password
     * @param string $newPassword
     * @return int
     */
    public function changePwd($account = '', $password = '', $newPassword = '', $type = 0)
    {
        $account = trim($account);
        $password = trim($password);
        $map = [];
        $map['status'] = 1;
        $map['mobile'] = $account;
        $member = self::where($map)->field('id,password,tradepwd')->find();
        if (!$member) {
            return -1;
        }
        $member = $member->toArray();
        if ($type == 0) {
            $memberPwd = $member['password'];
        } else {
            $memberPwd = $member['tradepwd'];
        }
        // 密码校验
        if (!password_verify($password, $memberPwd)) {
            return -2;
        }
        if ($type == 0) {
            $saveData['password'] = $newPassword;
        } else {
            $saveData['tradepwd'] = $newPassword;
        }
        $res = self::isUpdate(true, $map)->save($saveData);
        if ($res === false) {
            return 0;
        } else {
            return 1;
        }
    }


    /**
     * 用户详情
     * @author
     * @param $userId
     * @return array|bool|false|\PDOStatement|string|Model
     */
    public function userDetail($userId)
    {
        if ($userId > 0) {
            $map['id'] = $userId;
            $map['status'] = 1;
            $userInfo = self::where($map)->field('id,nick,mobile,avatar,signature')->find();
            return $userInfo ? $userInfo : array();
        } else {
            return false;
        }
    }

    /**
     * 验证用户密码
     * @author
     * @param $userId
     * @param $password
     * @return bool
     */
    public function verifyPassword($userId, $password)
    {
        $map = [];
        $map['status'] = 1;
        $map['id'] = $userId;
        $member = self::where($map)->field('id,password,tradepwd')->find();
        if (!password_verify($password, $member['tradepwd'])) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * 获取邀请码
     * @author
     * @return string
     */
    public function getYqCode()
    {
        $str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
        $code = str_pad(rand(0, 999999), 6, '0', STR_PAD_LEFT);
        $yqcode = $str[rand(0, 25)] . $code;
        $res = self::where('invit_code', $yqcode)->find();
        if ($res) {
            $yqcode = $this->getYqCode();
            return $yqcode;
        } else {
            return $yqcode;
        }
    }

    /**
     * 获取邀请列表
     * @author
     * @param $invitCode
     * @param int $startNo
     * @param int $limit
     * @return array
     */
    public function getInvitList($invitCode, $startNo = 0, $limit = 10)
    {
        $map['who_invit'] = $invitCode;
        $map['status'] = 1;
        $startNo = $startNo * $limit;
        $invitList = self::where($map)->field('id,nick,avatar,mobile,ctime')->order('ctime desc')->limit($startNo, $limit)->select();
        return $invitList ? $invitList : [];
    }

    public function getInvitCount($invitCode){
        $map['who_invit'] = $invitCode;
        $map['status'] = 1;
        $invitCount = self::where($map)->count('id');
        return $invitCount ? $invitCount : 0;
    }

}
